package com.sduept.nwld.dataview.controller.core;

import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.generation.HydroGeneratingUnit;
import com.sduept.cim.model.generation.ThermalGeneratingUnit;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.wires.*;
import com.sduept.core.entity.IdentifiedObject;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.bigdata.weather.map.MapDataCache;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.dataserver.util.LibCheckBoxTreeNode;
import com.sduept.utils.PingYinUtil;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.PrimeFaces;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.CheckboxTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Named
@ViewScoped
public class EquipmentSelectorController extends AbstractController {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6250546447223200062L;
	@Autowired
	private CimManager cimMan;
	
	@Autowired
	private MapDataCache cimChe;
	
	private TreeNode root;
	
	private TreeNode selectedNode;
	
	private TreeNode[] selectedNodes ;
	
	private List<Substation> rootObjects = new ArrayList<Substation>();
	
	public static final String TREE_TYPE_Container = Substation.class.getSimpleName();
	public static final String TREE_TYPE_Equipment = "Equipment";
	public static final String TREE_TYPE_Dir = "1";
	private String filterStation;
	private Map<String,TreeNode> filters = new HashMap<>();
	private Map<String,String> filterResults = new HashMap<>();
	private String selectStationId= null;
	private String selectedType= null;

	@PostConstruct
	public void init() {
		try {				
			selectStationId = getParameter("stationId");
			selectedType = getParameter("selectedType");
			initTree();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private void initTree(){
		root = new CheckboxTreeNode();
		if(StringUtils.isEmpty(selectStationId)){
			rootObjects= cimChe.getS500List();//暂时只获取500的站
		} else {
			rootObjects.clear();
			rootObjects.add(cimMan.getStationById(selectStationId));
		}		
		genStationTreeNode(rootObjects);
	}
	private void addToFilter(String name,TreeNode node){
		String py =  PingYinUtil.getPingYinHeader(name);
		filters.put(name,node);
		filters.put(PingYinUtil.getPingYinHeader(name),node);
		filterResults.put(name,name);
		filterResults.put(py,name);
	}
	private void genStationTreeNode(List<Substation> roots){
		for(Substation sub:roots){
			CheckboxTreeNode subNode  = new CheckboxTreeNode(Substation.class.getSimpleName(),sub,root);
			addToFilter(sub.getName(),subNode);
			if(roots.size()==1){
				subNode.setExpanded(true);
			}
			if(StringUtils.isNotEmpty(selectedType)){
				if("ACLineSegment".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"线路"), subNode);
				} if("PowerTransformer".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"变压器"), subNode);
				} if("Breaker".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"断路器"), subNode);
				} if("BusbarSection".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"母线"), subNode);
				} if("Compensator".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"补偿器"), subNode);
				} if("ProtectionEquipment".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"保护"), subNode);
				}if("Generating".equals(selectedType)){
					new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"发电机组"), subNode);
				}
			} else {
				new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"线路"), subNode);
				new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"变压器"), subNode);
				new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"断路器"), subNode);
				new LibCheckBoxTreeNode(TREE_TYPE_Dir,  new DirNode(sub.getId(),"母线"), subNode);
				new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"补偿器"), subNode);
				new LibCheckBoxTreeNode(TREE_TYPE_Dir, new DirNode(sub.getId(),"保护"), subNode);
			}
			
		}
	}
	public class DirNode {
		public String id;
		public String name;
		@Override
		public String toString() {
			return name;
		}
		public DirNode(String id,String name){
			this.id = id;
			this.name = name;
		}
	}
	private void expand(TreeNode currentNode){
		if(currentNode.getData() instanceof DirNode){
			DirNode currentObj = (DirNode) currentNode.getData();
			if("线路".equals(currentObj.name)){
				List<ACLineSegment> beans = cimMan.getAcLineSegmentsBySubstation(currentObj.id);
				for (ACLineSegment bean : beans) {
					CheckboxTreeNode subNode =  new CheckboxTreeNode(TREE_TYPE_Equipment,  bean, currentNode);
					 addToFilter(bean.getName(),subNode);
				}
			} else if("断路器".equals(currentObj.name)){
				List<Breaker> beans = cimMan.getBreakersByStationId(currentObj.id);
				for (Breaker bean : beans) {
					CheckboxTreeNode subNode =  new CheckboxTreeNode(TREE_TYPE_Equipment,  bean, currentNode);
					 addToFilter(bean.getName(),subNode);
				}
			} else if("母线".equals(currentObj.name)){
				List<BusbarSection> beans = cimMan.getBusbarSectionsByStationId(currentObj.id);
				for (BusbarSection bean : beans) {
					CheckboxTreeNode subNode =  new CheckboxTreeNode(TREE_TYPE_Equipment,  bean, currentNode);
					 addToFilter(bean.getName(),subNode);
					 
				}
			} else if("变压器".equals(currentObj.name)){
				List<PowerTransformer> beans = cimMan.getPowerTransformersByStationId(currentObj.id);
				
				for (PowerTransformer bean : beans) {
					 TreeNode node = new LibCheckBoxTreeNode(TREE_TYPE_Equipment,bean, currentNode);
					 addToFilter(bean.getName(),node);
					 List<TransformerWinding> beans1 =cimMan.getTransformerWindingsBypowerTransformerRdfId(bean.getRdfId());
					 for (TransformerWinding bean1 : beans1) {
						 CheckboxTreeNode subNode =   new CheckboxTreeNode(TREE_TYPE_Equipment, bean1, node);
						 addToFilter(bean1.getName(),subNode);
						}
				}
			} else if("电抗器".equals(currentObj.name)){
				List<Compensator> beans = cimMan.getCompensatorsByStationId(currentObj.id);
				for (Compensator bean : beans) {
					CheckboxTreeNode subNode = new CheckboxTreeNode(TREE_TYPE_Equipment,  bean, currentNode);
					 addToFilter(bean.getName(),subNode);
				}
			}else if("保护".equals(currentObj.name)){
				List<ProtectionEquipment> beans=cimMan.getProtectionEquipmentsByStationId(currentObj.id);
				for (ProtectionEquipment bean : beans) {
					CheckboxTreeNode subNode = new CheckboxTreeNode(TREE_TYPE_Equipment, bean, currentNode);
					 addToFilter(bean.getName(),subNode);
				}
			}else if("发电机组".equals(currentObj.name)){
				List<HydroGeneratingUnit> hu = cimMan.getHydroGeneratingUnitsByStationId(currentObj.id);
				for (HydroGeneratingUnit hydroGeneratingUnit : hu) {
					CheckboxTreeNode subNode = new CheckboxTreeNode(TREE_TYPE_Equipment, hydroGeneratingUnit, currentNode);
					 addToFilter(hydroGeneratingUnit.getName(),subNode);
				}
				List<ThermalGeneratingUnit> tu = cimMan.getThermalGeneratingUnitsByStationId(currentObj.id);
				for (ThermalGeneratingUnit thermalGeneratingUnit : tu) {
					CheckboxTreeNode subNode = new CheckboxTreeNode(TREE_TYPE_Equipment, thermalGeneratingUnit, currentNode);
					 addToFilter(thermalGeneratingUnit.getName(),subNode);
				}
			}
		}
	}
	public void onNodeExpand(NodeExpandEvent event){
		TreeNode node = event.getTreeNode();
		expand(node);
	}

	public void onNodeSelect(NodeSelectEvent event){
		selectedNode= event.getTreeNode();
	} 
	public void selectSingleDialog(){
		//单选
		if(selectedNode!=null){
			IdentifiedObject select =null;
			if((TREE_TYPE_Equipment.equals(selectedNode.getType()))||(TREE_TYPE_Container.equals(selectedNode.getType()))){
				select=(IdentifiedObject) selectedNode.getData();
			}
			PrimeFaces.current().dialog().closeDynamic(select);
		}else{
			addErrorMessage("请选择设备");
		}
	}
	public void selectCheckboxDialog(){
		//多选
		List<IdentifiedObject> select =new ArrayList<>();
		for(int i=0;i<selectedNodes.length;i++){
			if(TREE_TYPE_Equipment.equals(selectedNodes[i].getType())){
				select.add((IdentifiedObject) (selectedNodes[i].getData()));
			}
		}
		PrimeFaces.current().dialog().closeDynamic(select);
	}
	
	public List<String> completeEquipments(String query) {
		List<String> results = new ArrayList<String>();
		for (String s1 : filterResults.keySet()) {
			if (s1.startsWith(query)){
				results.add(filterResults.get(s1));
			} 
		}
		return results;
	}	
	public void autoCompleteStation(SelectEvent event){
		Object item = event.getObject();
		if(null != item){
			TreeNode sn = filters.get(item.toString());
			root.getChildren().clear();
			TreeNode n = expandParentNode(sn);
			root.getChildren().add(n);
			sn.setSelected(true);
		}
	}
	private TreeNode expandParentNode(TreeNode node){
		TreeNode pNode = node.getParent();
		if(pNode != null){
			if(pNode.getRowKey() == "root"){
				return node;
			}
			if(!pNode.isExpanded()){
				pNode.setExpanded(true);
			}
			return expandParentNode(pNode);
		} else {
			return node;
		}
	}
	public void refresh(){
		filterStation = null;
		initTree();
	}
	public TreeNode getRoot() {
		return root;
	}

	public void setRoot(TreeNode root) {
		this.root = root;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}

	public TreeNode[] getSelectedNodes() {
		return selectedNodes;
	}

	public void setSelectedNodes(TreeNode[] selectedNodes) {
		this.selectedNodes = selectedNodes;
	}
	public String getFilterStation() {
		return filterStation;
	}
	public void setFilterStation(String filterStation) {
		this.filterStation = filterStation;
	}
}
